package com.itlong.cloud.controller.huawei;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.itlong.cloud.POJO.DTO.property.IotCloudElevatorStateDTO;
import com.itlong.cloud.POJO.DTO.property.IotCloudEntranceStateDTO;
import com.itlong.cloud.POJO.PO.DeviceEntranceInfoPO;
import com.itlong.cloud.POJO.PO.DeviceOnlineStatusAlterLogPO;
import com.itlong.cloud.POJO.VO.sdk.CloudControllerNotifyMessageVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.equip.commons.ICloudDeviceBaseServiceClient;
import com.itlong.cloud.iottp.IIotDeviceOnlineServiceClient;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.sdkv3.service.ITaskService;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.encrypt.DesEncryptUtil;
import com.itlong.cloud.utils.network.https.HttpsPost;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 *      华为iot回调控制器
 * </desc>
 *
 * @createDate 2020/01/07
 */
@RestController
@RequestMapping("/huawei/iot")
public class IotCallBackController {
    private static final Logger LOG = LoggerFactory.getLogger(IotCallBackController.class);

    @Autowired
    private RedisService redisService;

    @Autowired
    private IIotDeviceOnlineServiceClient iIotDeviceOnlineServiceClient;

    @Autowired
    private ICloudDeviceBaseServiceClient iCloudDeviceBaseServiceClient;

    @Autowired
    MessageSender messageSender;

    @Autowired
    ITaskService iTaskService;

//    @Value("${" + PlatformConstants.JD_PROJECT_ID + "}")
//    private String jdProjectId;
    @Value("${" + PlatformConstants.JD_URL + "}")
    private String jdUrl;
    @Value("${" + PlatformConstants.JD_APPID + "}")
    private String appid;
    @Value("${" + PlatformConstants.JD_SECRET + "}")
    private String appsecret;
    /**
     * <desc>
     * 华为iot设备状态回调入口
     * <desc/>
     *
     * @param
     * @return
     * @author Qiang.S
     * @createDate 2020/01/07
     */
    @ResponseBody
    @RequestMapping("/httpCallBackState")
    public String httpCallBackState() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            Date nowDate = new Date();
            String jsonStr = request.getAttribute("jsonStr").toString();
            JSONObject json = JSONObject.parseObject(JSONObject.parseObject(jsonStr).get("notify_data").toString());
            String deviceUnique;
            if(request.getAttribute("device_unique") == null){
                deviceUnique = request.getAttribute("deviceUnique").toString();
            }else {
                deviceUnique = request.getAttribute("device_unique").toString();
            }
            //先把日志打印出来
            LOG.info("【华为回调时传递的数据httpCallBackState】{} {}", deviceUnique, jsonStr);
            if (json.get("status") == null) {
                LOG.info("设备无状态信息");
                return null;
            }
            String status = json.get("status").toString();
            if(("1".equals(deviceUnique.substring(8,9))||"5".equals(deviceUnique.substring(8,9)))) {
                //获取JD设备项目编号
                String jdProjectId = redisService.get(PlatformConstants.JD_PROJECT_ID);
                if(StringUtils.isNotBlank(jdProjectId) && jdProjectId.contains(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique))){
                    //推送京东设备状态
                    Map<String, Object> params = new HashMap<>();
                    params.put("id", LogicIdUtil.bussinessId());
                    Map<String, Object> protocol = new HashMap<>();
                    protocol.put("version", "1.0");
                    protocol.put("name", "JD-IOT-ESTATE-DEVICE");
                    Map<String, Object> client = new HashMap<>();
                    client.put("appid", appid);
                    Map<String, Object> param = new HashMap<>();
                    String jdDeviceId = iIotDeviceOnlineServiceClient.getJdDeviceId(deviceUnique, StringHandlerUtil.getDeviceTypeByDeviceUnique(deviceUnique));
                    if (StringUtils.isNotBlank(jdDeviceId)) {
                        param.put("deviceId", jdDeviceId);
                        param.put("status", status.equals("ONLINE") ? "1" : "0");
                        params.put("protocol", protocol);
                        params.put("client", client);
                        params.put("params", param);
                        try {
                            params = DesEncryptUtil.getJdSign(JsonUtil.toJSON(params), PlatformConstants.JD_CHANGEONLINESTATUS_URL, appsecret);
                            HttpsPost.doJdPost(jdUrl + PlatformConstants.JD_CHANGEONLINESTATUS_URL, JsonUtil.toJSON(params));
                        } catch (Exception e) {
                            LOG.error("【iot定时任务设备在线状态获取京东加密参数失败】", e);
                        }
                    }
                }
            }

            if ("ONLINE".equals(status)) {
                if ("1".equals(deviceUnique.substring(8,9))) {//云电梯
                    redisService.set(RedisConstant.DEVICE_ELEVATOR_IS_ONLINE_KEY+deviceUnique,"1");
                    //保存上下线日志
                    DeviceOnlineStatusAlterLogPO deviceOnlineStatusAlterLogPO = new DeviceOnlineStatusAlterLogPO();
                    deviceOnlineStatusAlterLogPO.setOnlineStatus(1);
                    deviceOnlineStatusAlterLogPO.setDeviceType(0);
                    deviceOnlineStatusAlterLogPO.setDeviceUnique(deviceUnique);
                    deviceOnlineStatusAlterLogPO.setCreateTime(nowDate);
                    deviceOnlineStatusAlterLogPO.setStatusAlterTime(nowDate);
                    deviceOnlineStatusAlterLogPO.setStatus(1);
                    iCloudDeviceBaseServiceClient.saveDeviceOnlineStatusAlterLog(deviceOnlineStatusAlterLogPO);
                }else if ("5".equals(deviceUnique.substring(8,9))) {//群控器
                    redisService.set(RedisConstant.DEVICE_CLUSTER_IS_ONLINE_KEY+deviceUnique,"1");
                    //保存上下线日志
                    DeviceOnlineStatusAlterLogPO deviceOnlineStatusAlterLogPO = new DeviceOnlineStatusAlterLogPO();
                    deviceOnlineStatusAlterLogPO.setOnlineStatus(1);
                    deviceOnlineStatusAlterLogPO.setDeviceType(3);
                    deviceOnlineStatusAlterLogPO.setDeviceUnique(deviceUnique);
                    deviceOnlineStatusAlterLogPO.setCreateTime(nowDate);
                    deviceOnlineStatusAlterLogPO.setStatusAlterTime(nowDate);
                    deviceOnlineStatusAlterLogPO.setStatus(1);
                    iCloudDeviceBaseServiceClient.saveDeviceOnlineStatusAlterLog(deviceOnlineStatusAlterLogPO);
                }else if ("2".equals(deviceUnique.substring(8,9))) {//云门禁,联动器
                    List<DeviceEntranceInfoPO> list = iIotDeviceOnlineServiceClient.getAllDoorByDeviceUnique(deviceUnique);
                    if (list.size() == 0) {
                        list = iIotDeviceOnlineServiceClient.getDoorByGroup(deviceUnique);
                    }
                    for (DeviceEntranceInfoPO po : list) {
                        if (po.getEntranceCategory() ==22 || po.getEntranceCategory() ==25) {//门禁
                            redisService.set(RedisConstant.DEVICE_ENTRANCE_IS_ONLINE_KEY+po.getDeviceUnique(),"1");
                            //保存上下线日志
                            DeviceOnlineStatusAlterLogPO deviceOnlineStatusAlterLogPO = new DeviceOnlineStatusAlterLogPO();
                            deviceOnlineStatusAlterLogPO.setOnlineStatus(1);
                            deviceOnlineStatusAlterLogPO.setDeviceType(2);
                            deviceOnlineStatusAlterLogPO.setDeviceUnique(po.getDeviceUnique());
                            deviceOnlineStatusAlterLogPO.setCreateTime(nowDate);
                            deviceOnlineStatusAlterLogPO.setStatusAlterTime(nowDate);
                            deviceOnlineStatusAlterLogPO.setStatus(1);
                            iCloudDeviceBaseServiceClient.saveDeviceOnlineStatusAlterLog(deviceOnlineStatusAlterLogPO);
                        }else if (po.getEntranceCategory() ==23) {//联动器
                            redisService.set(RedisConstant.DEVICE_WIPPEN_IS_ONLINE_KEY+po.getDeviceUnique(),"1");
                            //保存上下线日志
                            DeviceOnlineStatusAlterLogPO deviceOnlineStatusAlterLogPO = new DeviceOnlineStatusAlterLogPO();
                            deviceOnlineStatusAlterLogPO.setOnlineStatus(1);
                            deviceOnlineStatusAlterLogPO.setDeviceType(4);
                            deviceOnlineStatusAlterLogPO.setDeviceUnique(po.getDeviceUnique());
                            deviceOnlineStatusAlterLogPO.setCreateTime(nowDate);
                            deviceOnlineStatusAlterLogPO.setStatusAlterTime(nowDate);
                            deviceOnlineStatusAlterLogPO.setStatus(1);
                            iCloudDeviceBaseServiceClient.saveDeviceOnlineStatusAlterLog(deviceOnlineStatusAlterLogPO);
                        }else if (po.getEntranceCategory() ==24) {//一体式人脸识别门禁
                            redisService.set(RedisConstant.DEVICE_UNIBODY_FACE_IS_ONLINE_KEY+po.getDeviceUnique(),"1");
                            //保存上下线日志
                            DeviceOnlineStatusAlterLogPO deviceOnlineStatusAlterLogPO = new DeviceOnlineStatusAlterLogPO();
                            deviceOnlineStatusAlterLogPO.setOnlineStatus(1);
                            deviceOnlineStatusAlterLogPO.setDeviceType(6);
                            deviceOnlineStatusAlterLogPO.setDeviceUnique(po.getDeviceUnique());
                            deviceOnlineStatusAlterLogPO.setCreateTime(nowDate);
                            deviceOnlineStatusAlterLogPO.setStatusAlterTime(nowDate);
                            deviceOnlineStatusAlterLogPO.setStatus(1);
                            iCloudDeviceBaseServiceClient.saveDeviceOnlineStatusAlterLog(deviceOnlineStatusAlterLogPO);
                        }
                    }
                }
            } else if ("OFFLINE".equals(status)) {

                if ("1".equals(deviceUnique.substring(8,9))) {//云电梯,联动器
                    redisService.del(RedisConstant.DEVICE_ELEVATOR_IS_ONLINE_KEY+deviceUnique);
                    //保存上下线日志
                    DeviceOnlineStatusAlterLogPO deviceOnlineStatusAlterLogPO = new DeviceOnlineStatusAlterLogPO();
                    deviceOnlineStatusAlterLogPO.setOnlineStatus(0);
                    deviceOnlineStatusAlterLogPO.setDeviceType(0);
                    deviceOnlineStatusAlterLogPO.setDeviceUnique(deviceUnique);
                    deviceOnlineStatusAlterLogPO.setCreateTime(nowDate);
                    deviceOnlineStatusAlterLogPO.setStatusAlterTime(nowDate);
                    deviceOnlineStatusAlterLogPO.setStatus(1);
                    iCloudDeviceBaseServiceClient.saveDeviceOnlineStatusAlterLog(deviceOnlineStatusAlterLogPO);
                }else if ("5".equals(deviceUnique.substring(8,9))) {//群控器
                    redisService.del(RedisConstant.DEVICE_CLUSTER_IS_ONLINE_KEY+deviceUnique);
                    //保存上下线日志
                    DeviceOnlineStatusAlterLogPO deviceOnlineStatusAlterLogPO = new DeviceOnlineStatusAlterLogPO();
                    deviceOnlineStatusAlterLogPO.setOnlineStatus(0);
                    deviceOnlineStatusAlterLogPO.setDeviceType(3);
                    deviceOnlineStatusAlterLogPO.setDeviceUnique(deviceUnique);
                    deviceOnlineStatusAlterLogPO.setCreateTime(nowDate);
                    deviceOnlineStatusAlterLogPO.setStatusAlterTime(nowDate);
                    deviceOnlineStatusAlterLogPO.setStatus(1);
                    iCloudDeviceBaseServiceClient.saveDeviceOnlineStatusAlterLog(deviceOnlineStatusAlterLogPO);
                }else if ("2".equals(deviceUnique.substring(8,9))) {//云门禁
                    List<DeviceEntranceInfoPO> list = iIotDeviceOnlineServiceClient.getAllDoorByDeviceUnique(deviceUnique);
                    if (list.size() == 0) {
                        list = iIotDeviceOnlineServiceClient.getDoorByGroup(deviceUnique);
                    }
                    for (DeviceEntranceInfoPO po : list) {
                        if (po.getEntranceCategory() ==22 || po.getEntranceCategory() ==25) {//门禁
                            redisService.del(RedisConstant.DEVICE_ENTRANCE_IS_ONLINE_KEY+po.getDeviceUnique());
                            //保存上下线日志
                            DeviceOnlineStatusAlterLogPO deviceOnlineStatusAlterLogPO = new DeviceOnlineStatusAlterLogPO();
                            deviceOnlineStatusAlterLogPO.setOnlineStatus(0);
                            deviceOnlineStatusAlterLogPO.setDeviceType(2);
                            deviceOnlineStatusAlterLogPO.setDeviceUnique(po.getDeviceUnique());
                            deviceOnlineStatusAlterLogPO.setCreateTime(nowDate);
                            deviceOnlineStatusAlterLogPO.setStatusAlterTime(nowDate);
                            deviceOnlineStatusAlterLogPO.setStatus(1);
                            iCloudDeviceBaseServiceClient.saveDeviceOnlineStatusAlterLog(deviceOnlineStatusAlterLogPO);
                        }else if (po.getEntranceCategory() ==23) {//联动器
                            redisService.del(RedisConstant.DEVICE_WIPPEN_IS_ONLINE_KEY+po.getDeviceUnique());
                            //保存上下线日志
                            DeviceOnlineStatusAlterLogPO deviceOnlineStatusAlterLogPO = new DeviceOnlineStatusAlterLogPO();
                            deviceOnlineStatusAlterLogPO.setOnlineStatus(0);
                            deviceOnlineStatusAlterLogPO.setDeviceType(4);
                            deviceOnlineStatusAlterLogPO.setDeviceUnique(po.getDeviceUnique());
                            deviceOnlineStatusAlterLogPO.setCreateTime(nowDate);
                            deviceOnlineStatusAlterLogPO.setStatusAlterTime(nowDate);
                            deviceOnlineStatusAlterLogPO.setStatus(1);
                            iCloudDeviceBaseServiceClient.saveDeviceOnlineStatusAlterLog(deviceOnlineStatusAlterLogPO);
                        }else if (po.getEntranceCategory() ==24) {//一体式人脸识别门禁
                            redisService.del(RedisConstant.DEVICE_UNIBODY_FACE_IS_ONLINE_KEY+po.getDeviceUnique());
                            //保存上下线日志
                            DeviceOnlineStatusAlterLogPO deviceOnlineStatusAlterLogPO = new DeviceOnlineStatusAlterLogPO();
                            deviceOnlineStatusAlterLogPO.setOnlineStatus(0);
                            deviceOnlineStatusAlterLogPO.setDeviceType(6);
                            deviceOnlineStatusAlterLogPO.setDeviceUnique(po.getDeviceUnique());
                            deviceOnlineStatusAlterLogPO.setCreateTime(nowDate);
                            deviceOnlineStatusAlterLogPO.setStatusAlterTime(nowDate);
                            deviceOnlineStatusAlterLogPO.setStatus(1);
                            iCloudDeviceBaseServiceClient.saveDeviceOnlineStatusAlterLog(deviceOnlineStatusAlterLogPO);
                        }
                    }
                }
            }
        } catch (Exception e) {
            LOG.error("【华为IOT在线离线状态回调上报数据失败",e);
            e.printStackTrace();
        }
        LOG.info("【华为IOT在线离线状态回调上报数据成功");
        return null;
    }


    /**
     * <desc>
     * 华为iot设备信息上报回调入口
     * <desc/>
     *
     * @param
     * @return
     * @author Qiang.S
     * @createDate 2020/01/07
     */
    @ResponseBody
    @RequestMapping("/httpCallBackInfo")
    public String httpCallBackInfo() {
        HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            Object jsonObject2 = request.getAttribute("jsonStr");
            if (jsonObject2 == null) {
                return null;
            }
            String jsonStr = jsonObject2.toString();
            List<Map<String,Object>> list = JsonUtil.decode(jsonStr, new TypeReference<List<Map<String, Object>>>() {});
            String deviceUnique = request.getAttribute("deviceUnique").toString();
            //先把日志打印出来
            LOG.info("【华为回调时传递的数据httpCallBackInfo】{} {}", deviceUnique, jsonStr);
            for(Map<String,Object> mp : list){
                if (mp.get("service_id") == null ||  mp.get("data") == null) {//设备上报状态
                    continue;
                }
                //sdkv3自己处理消息 start
                LOG.info("【传给sdkv3的数据】{} {}", deviceUnique, mp);
                iTaskService.huaWeiCallback(deviceUnique, mp);
                //sdkv3自己处理消息 end
                String data = JsonUtil.toJSON(mp.get("data"));
                if ("1".equals(deviceUnique.substring(8,9))) {//云电梯
                    IotCloudElevatorStateDTO dto = JsonUtil.toObject(data, IotCloudElevatorStateDTO.class);
                    dto.setDeviceName(deviceUnique);
                    if(StringUtils.isNotBlank(dto.getFloor()) && !dto.getFloor().equals("-")) {
                        dto.setOverdue(DateUtil.addCurrentTime(new Date(), 120000).getTime());
                        //判断电梯状态是否是开门状态或开门到位状态，如果为是，需处理用户云电梯操作记录表当前处于预约状态的用户行程，并满足一定条件后将行程改为预约完成
                        if ((StringUtils.isNotBlank(dto.getFrontDoor()) && (!dto.getFrontDoor().equals("-1")))
                                || (StringUtils.isNotBlank(dto.getBackDoor()) && (!dto.getBackDoor().equals("-1")))) {
                            dto.setOpen(1);
                            JSONObject jsonObject = new JSONObject();
                            jsonObject.put("data", JsonUtil.toJSON(dto));
                            messageSender.send(RabbitMQConstant.RABBITMQ_CALL_ELEVATOR_OPERATE_STATUS_QUEUE,
                                    jsonObject.toJSONString(), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                                    RabbitMQConstant.RABBITMQ_CALL_ELEVATOR_OPERATE_STATUS_KEY);
                        }
                        //设置缓存
                        redisService.set(RedisConstant.REDIS_IOT_CLOUD_ELEVATOR_STATE_CACHE + deviceUnique + "_" +
                                dto.getTimestamp(), RedisConstant.REDIS_IOT_CLOUD_ELEVATOR_STATE_CACHE_TIME, dto);
                    }
                } else if ("5".equals(deviceUnique.substring(8,9))) {//群控器
                    CloudControllerNotifyMessageVO dto = JsonUtil.toObject(data, CloudControllerNotifyMessageVO.class);
                    dto.setDeviceName(deviceUnique);
                    dto.setData(JsonUtil.toObject(data, HashMap.class));
                    if(StringUtils.isNotBlank(dto.getRobotId())){
                        //设置缓存
                        redisService.set(RedisConstant.REDIS_IOT_CLOUD_CONTROLLER_NOTIFY_MESSAGE_CACHE +
                                        dto.getDeviceName() + dto.getRobotId() + "_" + dto.getTimestamp(),
                                RedisConstant.REDIS_IOT_CLOUD_CONTROLLER_NOTIFY_MESSAGE_CACHE_TIME, dto);
                    }
                } else if ("2".equals(deviceUnique.substring(8,9))) {//云门禁
                    IotCloudEntranceStateDTO dto = JsonUtil.toObject(data, IotCloudEntranceStateDTO.class);
                    dto.setDeviceName(String.format("%s%s", deviceUnique.substring(0, 9), StringHandlerUtil.autlSupply(4,dto.getDoorNum(),"0")));
                    //设置缓存
                    LOG.info("收到华为云iot回调】" +dto.toString() +"----currentTimeStamp" + System.currentTimeMillis());
                    redisService.set(RedisConstant.REDIS_IOT_CLOUD_ENTRANCE_STATE_CACHE +
                                   dto.getDeviceName()
                                    + "_" + dto.getTimestamp(),
                            RedisConstant.REDIS_IOT_CLOUD_ENTRANCE_STATE_CACHE_TIME, dto);
                }
            }
        } catch (Exception e) {
            LOG.error("【华为云获取iot上报数据失败",e);
        }
        return null;
    }
}
